package com.atguigu.gmall.mq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: 封捷
 * @create-date: 2022/9/11 8:42
 */
@Configuration
public class DeadLetterConfig {

    // 对应常规队列的交换机名称
    public static final String EXCHANGE_NORMAL_NAME = "exchange.normal.bar";

    // 对应死信队列的交换机名称
    public static final String EXCHANGE_DEAD_NAME = "exchange.dead.bar";

    // 对应常规队列的路由键名称
    public static final String ROUTING_KEY_NORMAL_NAME = "routing.key.normal.bar";

    // 对应死信队列的路由键名称
    public static final String ROUTING_KEY_DEAD_NAME = "routing.key.dead.bar";

    // 常规队列名称
    public static final String QUEUE_NORMAL_NAME = "queue.normal.bar";

    // 死信队列名称
    public static final String QUEUE_DEAD_NAME = "queue.dead.bar";

    @Bean
    public DirectExchange getExchangeNormal() {
        // 创建对应常规队列的交换机对象
        return new DirectExchange(EXCHANGE_NORMAL_NAME, true, false);
    }

    @Bean
    public DirectExchange getExchangeDead() {
        // 创建对应死信队列的交换机对接
        return new DirectExchange(EXCHANGE_DEAD_NAME, true, false);
    }

    @Bean
    public Queue getQueueNormal() {

        // 封装当前队列需要的参数
        Map<String, Object> map = new HashMap<>();

        // 设置当前队列中消息超时的时间
        map.put("x-message-ttl", 15 * 1000);

        // 设置当前队列中消息超时后要转入的交换机
        map.put("x-dead-letter-exchange", EXCHANGE_DEAD_NAME);

        // 设置转入死信交换机之后，进一步要查找的路由键，通过这个路由键是为了找到对应的死信队列
        map.put("x-dead-letter-routing-key", ROUTING_KEY_DEAD_NAME);

        // 基于上面封装的参数，创建队列对象
        return new Queue(QUEUE_NORMAL_NAME, true, false, false, map);
    }

    @Bean
    public Queue getQueueDead() {
        // 创建死信队列，不需要特殊参数，等待死信消息转入即可
        return new Queue(QUEUE_DEAD_NAME, true, false, false);
    }

    @Bean
    public Binding getNormalBinding() {
        // 把『常规队列』绑定到『常规交换机』，通过谁绑定的呢？通过『常规路由键』绑定的
        return BindingBuilder.bind(getQueueNormal()).to(getExchangeNormal()).with(ROUTING_KEY_NORMAL_NAME);
    }

    @Bean
    public Binding getDeadBinding() {
        // 把『死信队列』绑定到『死信交换机』，通过谁绑定的呢？通过『死信路由键』绑定的
        return BindingBuilder.bind(getQueueDead()).to(getExchangeDead()).with(ROUTING_KEY_DEAD_NAME);
    }
}
